#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

from common.common import exter_attack, output_result_file, report_job_details
from common.common_models import SubJobDetails, LogDetail
from common.common_models import ActionResult
from common.const import ExecuteResultEnum, SubJobStatusEnum
from goldendb.handle.common.const import LogLevel
from tpops.gaussdb.common.const import ErrorCode
from tpops.gaussdb.common.gaussdb_common import is_valid_port, is_valid_ip, add_resource_info
from tpops.gaussdb.common.gaussdb_pydantic import ListAppV2Response
from tpops.gaussdb.common.safe_get_information import ResourceParam
from tpops.gaussdb.handle.resource.resource_info import ResourceInfo
from tpops.gaussdb.common.log import log
from tpops.gaussdb.common.const import EnvName, QUERY_SIZE


class ResourceAbility:
    @staticmethod
    @exter_attack
    def check_application(req_id, job_id, sub_id, data):
        """
        通用接口: 检查项目连通性
        """
        log.info(f"step 1-1: start to check application.")
        check_output = ActionResult(code=ExecuteResultEnum.SUCCESS)
        # 组装资源接入请求体
        EnvName.IAM_USERNAME = "appEnv_auth_authKey"
        EnvName.IAM_PASSWORD = "appEnv_auth_authPwd"
        param_inst = ResourceParam(req_id)
        # 业务地址: endpoint地址
        project_addr = param_inst.get_business_addr()
        project_port = param_inst.get_business_port()
        if not is_valid_port(project_port):
            log.info("invalid port")
            raise Exception("invalid port")
        if not is_valid_ip(project_addr):
            log.info("invalid ip")
            raise Exception("invalid ip")
        address = f"https://{project_addr}:{project_port}"
        fun_inst = ResourceInfo(req_id, address)
        if not fun_inst.db_version:
            log.error("Failed get db_version!")
            check_output.code = ExecuteResultEnum.INTERNAL_ERROR
            check_output.body_err = ErrorCode.ERR_RESOURCE_ABILITY.value
            check_output.message = "tpops_password_error"
            output_result_file(req_id, check_output.dict(by_alias=True))
            return True
        # 获取token
        log.info(f"start to request for token")
        token = fun_inst.get_token_info()
        if not token:
            log.warning("Failed get Token!")
            check_output.code = ExecuteResultEnum.INTERNAL_ERROR
            check_output.body_err = ErrorCode.ERR_RESOURCE_ABILITY.value
            check_output.message = "Check application failed!"
            output_result_file(req_id, check_output.dict(by_alias=True))
            return True
        output_result_file(req_id, check_output.dict(by_alias=True))
        log.info(f"step 1-1: end to check application.")
        return True

    @staticmethod
    @exter_attack
    def query_cluster(req_id, job_id, sub_id, data):
        """
        通用接口: 查询项目版本
        """
        log.info(f"step 1-2: start to query_cluster.")
        log_detail = LogDetail(logInfo="plugin_task_subjob_success_label",
                               logLevel=LogLevel.INFO)
        report_job_details(req_id,
                           SubJobDetails(taskId=job_id, subTaskId=sub_id, progress=100, logDetail=[log_detail],
                                         taskStatus=SubJobStatusEnum.COMPLETED.value))
        log.info(f"step 1-2: end to query_cluster.")
        return True

    @staticmethod
    @exter_attack
    def list_application_v2(req_id, job_id, sub_id, data):
        """
        通用接口: 查询实例列表
        """
        log.info(f"step 1-3: start to list application v2.")
        check_output = ActionResult(code=ExecuteResultEnum.SUCCESS)
        # 组装资源接入执行体
        EnvName.IAM_USERNAME = "appEnv_auth_authKey"
        EnvName.IAM_PASSWORD = "appEnv_auth_authPwd"
        log.info(f"succeed: {EnvName.IAM_USERNAME}_{req_id}")
        param_inst = ResourceParam(req_id)
        # 业务地址: endpoint地址
        business_addr = param_inst.get_business_addr()
        business_port = param_inst.get_business_port()
        address = f"https://{business_addr}:{business_port}"
        fun_inst = ResourceInfo(req_id, address)
        # 查询实例列表
        offset = 0
        response = ListAppV2Response()
        while True:
            try:
                resource = fun_inst.get_instance_json(offset)
            except Exception as err:
                log.error(f"List application failed for {err.error_message}")
                check_output.code = ExecuteResultEnum.INTERNAL_ERROR
                check_output.body_err = ErrorCode.ERR_RESOURCE_ABILITY.value
                check_output.message = "List application failed!"
                output_result_file(req_id, check_output.dict(by_alias=True))
            cur_instance_num = len(resource.get("instances", []))
            response.total += cur_instance_num
            log.info(f"current instances number: {cur_instance_num}")
            for instance in resource.get("instances", []):
                add_resource_info(response, instance, fun_inst)
            offset += QUERY_SIZE
            if cur_instance_num < QUERY_SIZE:
                log.info(f"step 1-3: list_application_v2_result break")
                break
        log.info(f"step 1-3: list_application_v2_result: {response}")
        output_result_file(req_id, response.dict(by_alias=True))
        log.info(f"step 1-3: end to list application v2.")
        return True


